% flashattention_pareto_viz.m - FlashAttention双案例帕累托解可视化
% 基于Project3.2的simple_pareto_viz.m脚本设计
% 专门处理FlashAttention_Case0和FlashAttention_Case1数据

clear; clc; close all;

fprintf('=== FlashAttention双案例帕累托解可视化 ===\n\n');

% 设置工作目录
base_dir = 'E:\GMCM_2025_A\problem2and3pro\Problem3_MATLAB';

% 案例设置  
cases = {'FlashAttention_Case0', 'FlashAttention_Case1'};
case_names = {'FlashAttention-Case0', 'FlashAttention-Case1'};
colors = [0.0 0.3 0.8; 1.0 0.5 0.0];  % 深蓝色和橙色（与参考脚本一致）
markers = {'o', 's'};

% 数据读取
fprintf('1. 读取数据...\n');
data_loaded = {};
valid_cases = {};
valid_names = {};
valid_colors = [];

for i = 1:length(cases)
    case_name = cases{i};
    csv_file = fullfile(base_dir, case_name, [case_name '_pareto_solutions.csv']);
    
    fprintf('  检查: %s -> %s\n', case_name, csv_file);
    
    if exist(csv_file, 'file')
        try
            data = readtable(csv_file);
            data_loaded{end+1} = data;
            valid_cases{end+1} = cases{i};
            valid_names{end+1} = case_names{i};
            valid_colors = [valid_colors; colors(i,:)];
            
            fprintf('    ✓ 成功读取 %d 行数据\n', height(data));
            
            % 显示数据摘要
            unique_solutions = unique([data.time, data.spill], 'rows');
            strategies = unique(data.strategy_type);
            fprintf('      - 唯一解: %d/%d (%.1f%%)\n', size(unique_solutions,1), height(data), ...
                   size(unique_solutions,1)/height(data)*100);
            fprintf('      - 策略: %s\n', strjoin(strategies, ', '));
            fprintf('      - 时间范围: [%.0f, %.0f]\n', min(data.time), max(data.time));
            fprintf('      - Spill范围: [%.0f, %.0f]\n', min(data.spill), max(data.spill));
            
        catch ME
            fprintf('    ❌ 读取失败: %s\n', ME.message);
        end
    else
        fprintf('    ❌ 文件不存在\n');
    end
end

if isempty(data_loaded)
    fprintf('❌ 没有找到任何有效数据文件！\n');
    return;
end

fprintf('\n成功加载 %d 个FlashAttention案例的数据\n', length(data_loaded));

% 创建输出目录
output_dir = fullfile(base_dir, 'FlashAttention_Visualization');
if ~exist(output_dir, 'dir')
    mkdir(output_dir);
end

%% 图表1: 帕累托前沿对比
fprintf('\n2. 生成帕累托前沿对比图...\n');

figure('Position', [100, 100, 1200, 800], 'Color', 'white');
hold on;

for i = 1:length(data_loaded)
    data = data_loaded{i};
    
    % 去重
    [~, unique_idx] = unique([data.time, data.spill], 'rows');
    unique_data = data(unique_idx, :);
    
    % 绘制散点
    scatter(unique_data.time / 1000, unique_data.spill / 1000, 120, ...
            valid_colors(i,:), 'filled', 'Marker', markers{i}, ...
            'MarkerEdgeColor', 'black', 'LineWidth', 2.0, ...
            'DisplayName', sprintf('%s (%d解)', valid_names{i}, size(unique_data,1)));
    
    % 连线（如果有多个不同解）
    if size(unique_data, 1) > 1
        [sorted_time, sort_idx] = sort(unique_data.time);
        sorted_spill = unique_data.spill(sort_idx);
        h = plot(sorted_time / 1000, sorted_spill / 1000, '--', ...
             'Color', valid_colors(i,:), 'LineWidth', 2.0);
        % 设置透明度（兼容不同MATLAB版本）
        try
            h.Color(4) = 0.7;  % 设置alpha值
        catch
            % 如果不支持alpha，就使用浅一点的颜色
            light_color = valid_colors(i,:) * 0.7 + [0.3, 0.3, 0.3];
            h.Color = light_color;
        end
    end
end

xlabel('执行时间 (×10³ cycles)', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
ylabel('额外数据搬运量 (×10³ bytes)', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
title('FlashAttention双案例帕累托前沿对比分析', 'FontSize', 16, 'FontWeight', 'bold', 'Color', 'black');
legend('Location', 'best', 'FontSize', 12, 'EdgeColor', [0.5 0.5 0.5], 'TextColor', 'black', 'Color', 'white');
grid on;
set(gca, 'FontSize', 12, 'GridColor', 'black', 'GridAlpha', 0.3, 'LineWidth', 1.5, ...
    'XColor', 'black', 'YColor', 'black', 'Color', 'white', 'Box', 'on');

% 保存图表1
set(gcf, 'Color', 'white', 'InvertHardcopy', 'off');
pareto_file = fullfile(output_dir, 'flashattention_pareto_comparison.png');
print(gcf, pareto_file, '-dpng', '-r300');
saveas(gcf, strrep(pareto_file, '.png', '.fig'));
fprintf('  ✓ 保存: %s\n', pareto_file);

%% 图表2: 性能对比柱状图
fprintf('3. 生成性能对比图...\n');

figure('Position', [200, 100, 1400, 600], 'Color', 'white');

% 计算平均值
avg_times = [];
avg_spills = [];
diversity_scores = [];
threshold_ranges = [];

for i = 1:length(data_loaded)
    data = data_loaded{i};
    avg_times = [avg_times; mean(data.time)];
    avg_spills = [avg_spills; mean(data.spill)];
    
    unique_solutions = unique([data.time, data.spill], 'rows');
    diversity_scores = [diversity_scores; size(unique_solutions,1)/height(data)*100];
    
    % FlashAttention特有的threshold分析
    threshold_ranges = [threshold_ranges; max(data.min_farthest_use_threshold) - min(data.min_farthest_use_threshold)];
end

% 子图1: 平均执行时间
subplot(1, 3, 1);
b1 = bar(avg_times / 1000, 'FaceColor', 'flat', 'EdgeColor', 'black', 'LineWidth', 1.2);
b1.CData = valid_colors;
for i = 1:length(avg_times)
    text(i, avg_times(i)/1000 + max(avg_times)/1000*0.02, ...
         sprintf('%.0fK', avg_times(i)/1000), ...
         'HorizontalAlignment', 'center', 'FontSize', 10, 'FontWeight', 'bold', 'Color', 'black');
end
set(gca, 'XTickLabel', valid_names, 'XColor', 'black', 'YColor', 'black');
xtickangle(30);
ylabel('平均执行时间 (×10³ cycles)', 'FontSize', 12, 'FontWeight', 'bold', 'Color', 'black');
title('执行时间对比', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
grid on;
set(gca, 'FontSize', 11, 'GridColor', 'black', 'GridAlpha', 0.3, 'Box', 'on', 'LineWidth', 1.5, 'Color', 'white');

% 子图2: 平均Spill量
subplot(1, 3, 2);
b2 = bar(avg_spills / 1000, 'FaceColor', 'flat', 'EdgeColor', 'black', 'LineWidth', 1.2);
b2.CData = valid_colors;
for i = 1:length(avg_spills)
    text(i, avg_spills(i)/1000 + max(avg_spills)/1000*0.02, ...
         sprintf('%.0fK', avg_spills(i)/1000), ...
         'HorizontalAlignment', 'center', 'FontSize', 10, 'FontWeight', 'bold', 'Color', 'black');
end
set(gca, 'XTickLabel', valid_names, 'XColor', 'black', 'YColor', 'black');
xtickangle(30);
ylabel('平均Spill量 (×10³ bytes)', 'FontSize', 12, 'FontWeight', 'bold', 'Color', 'black');
title('Spill量对比', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
grid on;
set(gca, 'FontSize', 11, 'GridColor', 'black', 'GridAlpha', 0.3, 'Box', 'on', 'LineWidth', 1.5, 'Color', 'white');

% 子图3: 解的多样性
subplot(1, 3, 3);
b3 = bar(diversity_scores, 'FaceColor', 'flat', 'EdgeColor', 'black', 'LineWidth', 1.2);
b3.CData = valid_colors;
for i = 1:length(diversity_scores)
    text(i, diversity_scores(i) + max(diversity_scores)*0.02, ...
         sprintf('%.1f%%', diversity_scores(i)), ...
         'HorizontalAlignment', 'center', 'FontSize', 10, 'FontWeight', 'bold', 'Color', 'black');
end
set(gca, 'XTickLabel', valid_names, 'XColor', 'black', 'YColor', 'black');
xtickangle(30);
ylabel('解的多样性 (%)', 'FontSize', 12, 'FontWeight', 'bold', 'Color', 'black');
title('多样性对比', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
grid on;
set(gca, 'FontSize', 11, 'GridColor', 'black', 'GridAlpha', 0.3, 'Box', 'on', 'LineWidth', 1.5, 'Color', 'white');

% 总标题
sgtitle('FlashAttention双案例性能指标对比', 'FontSize', 16, 'FontWeight', 'bold', 'Color', 'black');

% 保存图表2
set(gcf, 'Color', 'white', 'InvertHardcopy', 'off');
performance_file = fullfile(output_dir, 'flashattention_performance_comparison.png');
print(gcf, performance_file, '-dpng', '-r300');
saveas(gcf, strrep(performance_file, '.png', '.fig'));
fprintf('  ✓ 保存: %s\n', performance_file);

%% 图表3: 策略分析（饼图）
fprintf('4. 生成策略分析图...\n');

figure('Position', [300, 150, 1200, 500], 'Color', 'white');

% 统计每个案例的策略分布
for i = 1:length(data_loaded)
    subplot(1, length(data_loaded), i);
    
    data = data_loaded{i};
    strategy_counts = countcats(categorical(data.strategy_type));
    strategy_labels = categories(categorical(data.strategy_type));
    
    % 避免空数据的pie函数错误
    if ~isempty(strategy_counts) && sum(strategy_counts) > 0
        pie_colors = repmat(valid_colors(i,:), length(strategy_labels), 1);
        pie_colors = pie_colors .* (0.7 + 0.3 * rand(size(pie_colors, 1), 1)); % 添加变化
        
        pie(strategy_counts, strategy_labels);
        colormap(pie_colors);
        
        title(sprintf('%s\n策略分布', valid_names{i}), 'FontSize', 13, 'FontWeight', 'bold', 'Color', 'black');
        
        % 设置文本颜色
        text_objs = findobj(gca, 'Type', 'text');
        set(text_objs, 'FontSize', 10, 'FontWeight', 'bold', 'Color', 'black');
    else
        text(0.5, 0.5, '无有效策略数据', 'HorizontalAlignment', 'center', ...
             'FontSize', 12, 'FontWeight', 'bold', 'Color', 'black');
        title(valid_names{i}, 'FontSize', 13, 'FontWeight', 'bold', 'Color', 'black');
    end
end

% 总标题
sgtitle('FlashAttention双案例策略分布分析', 'FontSize', 16, 'FontWeight', 'bold', 'Color', 'black');

% 保存图表3
set(gcf, 'Color', 'white', 'InvertHardcopy', 'off');
strategy_file = fullfile(output_dir, 'flashattention_strategy_analysis.png');
print(gcf, strategy_file, '-dpng', '-r300');
saveas(gcf, strrep(strategy_file, '.png', '.fig'));
fprintf('  ✓ 保存: %s\n', strategy_file);

%% 生成分析报告
fprintf('5. 生成分析报告...\n');

report_file = fullfile(output_dir, 'flashattention_analysis_report.txt');
fid = fopen(report_file, 'w');

fprintf(fid, '=== FlashAttention双案例分析报告 ===\n');
fprintf(fid, '生成时间: %s\n\n', datestr(now, 'yyyy-mm-dd HH:MM:SS'));

fprintf(fid, '1. 数据概览:\n');
for i = 1:length(data_loaded)
    data = data_loaded{i};
    unique_solutions = unique([data.time, data.spill], 'rows');
    
    fprintf(fid, '  %s:\n', valid_names{i});
    fprintf(fid, '    - 解的总数: %d\n', height(data));
    fprintf(fid, '    - 唯一解数: %d (多样性: %.1f%%)\n', size(unique_solutions,1), diversity_scores(i));
    fprintf(fid, '    - 平均执行时间: %.0f cycles\n', avg_times(i));
    fprintf(fid, '    - 平均Spill量: %.0f bytes\n', avg_spills(i));
    fprintf(fid, '    - 时间范围: [%.0f, %.0f] cycles\n', min(data.time), max(data.time));
    fprintf(fid, '    - Spill范围: [%.0f, %.0f] bytes\n', min(data.spill), max(data.spill));
    fprintf(fid, '    - Threshold范围: [%.2f, %.2f]\n', min(data.min_farthest_use_threshold), max(data.min_farthest_use_threshold));
    fprintf(fid, '\n');
end

if length(data_loaded) == 2
    fprintf(fid, '2. 案例间对比:\n');
    time_diff = abs(avg_times(2) - avg_times(1)) / avg_times(1) * 100;
    spill_diff = abs(avg_spills(2) - avg_spills(1)) / avg_spills(1) * 100;
    
    fprintf(fid, '  - 平均时间差异: %.1f%%\n', time_diff);
    fprintf(fid, '  - 平均Spill差异: %.1f%%\n', spill_diff);
    fprintf(fid, '  - 多样性差异: %.1f%% vs %.1f%%\n', diversity_scores(1), diversity_scores(2));
    
    if avg_times(1) < avg_times(2)
        fprintf(fid, '  - Case0在执行时间上表现更优\n');
    else
        fprintf(fid, '  - Case1在执行时间上表现更优\n');
    end
    
    if avg_spills(1) < avg_spills(2)
        fprintf(fid, '  - Case0在Spill量上表现更优\n');
    else
        fprintf(fid, '  - Case1在Spill量上表现更优\n');
    end
end

fprintf(fid, '\n3. 生成的图表:\n');
fprintf(fid, '  - flashattention_pareto_comparison.png/.fig - 帕累托前沿对比\n');
fprintf(fid, '  - flashattention_performance_comparison.png/.fig - 性能指标对比\n');
fprintf(fid, '  - flashattention_strategy_analysis.png/.fig - 策略分布分析\n');

fclose(fid);
fprintf('  ✓ 保存: %s\n', report_file);

%% 完成
fprintf('\n=== FlashAttention双案例可视化完成 ===\n');
fprintf('输出目录: %s\n', output_dir);
fprintf('共生成 %d 个图表文件和 1 个分析报告\n', length(data_loaded) * 2 + 2);

% 显示最终统计
fprintf('\n最终数据统计:\n');
for i = 1:length(data_loaded)
    fprintf('  %s: %.0fK cycles, %.0fK bytes, %.1f%% diversity\n', ...
            valid_names{i}, avg_times(i)/1000, avg_spills(i)/1000, diversity_scores(i));
end
